#include "DayTime_t.h"

static const std::string days[]={"Sunday","Monday","Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

const DayTime_t& DayTime_t::invalid = DayTime_t(); // Invalid type

DayTime_t::DayTime_t()
	: m_day(Day_t::Undefined)
	, m_hours(0)
	, m_minutes(0)
{
}

DayTime_t::DayTime_t(const Day_t& day, size_t hours, size_t minutes)
	: m_day(Day_t::Undefined)
	, m_hours(0)
	, m_minutes(0)
{
	if(!setDay(day) || !setHours(hours) || !setMinutes(minutes))
		throw "DayTime_t: Ctor parameters error";
}

DayTime_t::~DayTime_t()
{
}

DayTime_t::DayTime_t(const DayTime_t& other)
	: m_day(other.m_day)
	, m_hours(other.m_hours)
	, m_minutes(other.m_minutes)
{
}

DayTime_t& DayTime_t::operator=(const DayTime_t& other)
{
	if(this != &other)
	{
		m_day = other.m_day;
		m_hours = other.m_hours;
		m_minutes = other.m_minutes;
	}

	return *this;
}

bool DayTime_t::operator==(const DayTime_t& other) const
{
	return (m_day == other.m_day &&
		    m_hours == other.m_hours &&
			m_minutes == other.m_minutes);
}

bool DayTime_t::operator!=(const DayTime_t& other) const
{
	return !(*this == other);
}

bool DayTime_t::operator<=(const DayTime_t& other) const
{
	if(m_day > other.m_day)
		return false;

	if(m_day < other.m_day)
		return true;

	if(m_hours > other.m_hours)
		return false;

	if(m_hours < other.m_hours)
		return true;

	if(m_minutes > other.m_minutes)
		return false;

	return true;
}

bool DayTime_t::operator<(const DayTime_t& other) const
{
	return *this <= other && *this != other;
}

DayTime_t DayTime_t::operator+(const DayTime_t& other) const
{
	int hours = m_hours + other.m_hours;
	if(hours > 23)
		return DayTime_t::invalid;

	int minutes = m_minutes + other.m_minutes;
	if(minutes > 59) 
	{
		hours++;
		minutes -= 60;
	}

	if(hours > 23 || minutes > 59)
		return DayTime_t::invalid;

	return DayTime_t(m_day, hours, minutes);
}

DayTime_t DayTime_t::operator-(const DayTime_t& other) const
{
	int hours = m_hours - other.m_hours;
	if(hours < 0)
		return DayTime_t::invalid;

	int minutes = m_minutes - other.m_minutes;
	if(minutes < 0) 
	{
		hours--;
		minutes += 60;
	}

	if(hours < 0 || minutes < 0)
		return DayTime_t::invalid;

	return DayTime_t(m_day, hours, minutes);
}

std::ostream& operator<<(std::ostream& os, const DayTime_t& other)
{
	// empty space, for appointment hours
	os<<"|";
	os.fill(' ');
	os.width(15);
	os<<std::right;
	os<<"|";

	// output day name
	os<<std::left;
	os.fill(' ');
	os.width(45);
	os<<days[(other.day())-1];
	os<<"|"<<std::endl;
	
	// output seperating line
	os.fill('-');
	os.width(15);
	os<<std::left;
	os<<"|";
	os.width(46);
	os<<"|";
	os<<"|"<<std::endl;

	return os;
}